﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Controls;
using YArchitech.HCLoad.Controls;
using YArchitech.Revit;
using YJKArchMethodLibrary.Utils;
using HYFamilyLibDataManager;

namespace LinearArrayModule
{
	public partial class DlgLinearArray : System.Windows.Forms.Form
	{
		public static DlgLinearArray GetInstance(ExternalCommandData cmd)
		{
			if (DlgLinearArray.dla == null || DlgLinearArray.dla.IsDisposed)
			{
				DlgLinearArray.dla = new DlgLinearArray(cmd);
			}
			if (DlgLinearArray.dla.rbtProject.Checked)
			{
				DlgLinearArray.dla.getProjectFamily();
			}
			return DlgLinearArray.dla;
		}

		public DlgLinearArray(ExternalCommandData cmdData)
		{
			this.revit = cmdData;
			this.InitializeComponent();
		}

		private void DlgLinearArray_Load(object sender, EventArgs e)
		{
		}

		private void rbtProject_CheckedChanged(object sender, EventArgs e)
		{
			if (this.rbtProject.Checked)
			{
				this.getProjectFamily();
			}
		}

		private void getProjectFamily()
		{
			this.PlaceType = PlaceType.FamilySymbol;
			Dictionary<string, List<Family>> allFamily = this.GetAllFamily(this.revit.Application.ActiveUIDocument.Document);
			this.tvFamliy.Nodes.Clear();
			this.lbxType.Items.Clear();
			this.pictureBox1.Image = null;
			foreach (KeyValuePair<string, List<Family>> keyValuePair in allFamily)
			{
				string key = keyValuePair.Key;
				TreeNode treeNode = new TreeNode();
				treeNode.Text = key;
				treeNode.Tag = key;
				treeNode.Checked = true;
				this.tvFamliy.Nodes.Add(treeNode);
				foreach (Family family in keyValuePair.Value)
				{
					TreeNode treeNode2 = new TreeNode();
					treeNode2.Text = string.Format("{0}", family.Name);
					treeNode2.Tag = family;
					treeNode2.Checked = true;
					treeNode.Nodes.Add(treeNode2);
				}
			}
			this.temp = this.rbtProject;
		}

		public Dictionary<string, List<Family>> GetAllFamily(Autodesk.Revit.DB.Document doc)
		{
			Dictionary<string, List<Family>> dictionary = new Dictionary<string, List<Family>>();
			foreach (Family family in new FilteredElementCollector(doc).OfClass(typeof(Family)).WhereElementIsNotElementType().Cast<Family>().ToList<Family>())
			{
				if (family.get_Parameter(BuiltInParameter.FAMILY_HOSTING_BEHAVIOR).AsInteger() == 0)
				{
					Category familyCategory = RevitVersionFuncs.GetFamilyCategory(family);
					if (dictionary.ContainsKey(familyCategory.Name))
					{
						dictionary[familyCategory.Name].Add(family);
					}
					else
					{
						List<Family> list = new List<Family>();
						list.Add(family);
						dictionary.Add(familyCategory.Name, list);
					}
				}
			}
			return dictionary;
		}

		private void rbtLib_CheckedChanged(object sender, EventArgs e)
		{
			if (this.rbtLib.Checked)
			{
				this.PlaceType = PlaceType.FamilySymbol;
				try
				{
					this.dbs = FamilyLibDatabase.GetLocalDbs(this.revit.Application.Application.VersionNumber);
				}
				catch (Exception)
				{
					this.dbs = FamilyLibDatabase.GetLocalSystemDb(this.revit.Application.Application.VersionNumber);
				}
				if (this.dbs.Count < 1)
				{
					YJKMessageBox.Show("\n没有检测到本地族库，请安装族库。");
					this.temp.Checked = true;
					return;
				}
			}
			this.tvFamliy.Nodes.Clear();
			this.lbxType.Items.Clear();
			this.pictureBox1.Image = null;
			foreach (FamilyLibDatabase db in this.dbs)
			{
				DlgLinearArray.DataBaseFillTree(db, this.tvFamliy);
			}
		}

		private static void DataBaseFillTree(FamilyLibDatabase db, TreeView tree)
		{
			try
			{
				List<DbCategory> all = db.CategoryTable.GetAll();
				DbSubject dbSubject = db.SubjectTable.AllSubject()[0];
				TreeNode treeNode = new TreeNode(dbSubject.ToString());
				treeNode.Name = dbSubject.Name;
				treeNode.Tag = dbSubject;
				DlgLinearArray.SetChildNode(treeNode, all);
				tree.Nodes.Add(treeNode);
			}
			catch (Exception ex)
			{
				throw ex;
			}
		}

		private static void SetChildNode(TreeNode tn, List<DbCategory> cl)
		{
			foreach (DbCategory dbCategory in cl)
			{
				if (tn.Tag is DbCategory)
				{
					if (dbCategory.ParentId == ((DbCategory)tn.Tag).Guid)
					{
						TreeNode treeNode = new TreeNode(dbCategory.ToString());
						treeNode.Name = dbCategory.Name;
						treeNode.Tag = dbCategory;
						treeNode.ImageIndex = 1;
						if (dbCategory.Limit)
						{
							treeNode.ForeColor = System.Drawing.Color.Red;
						}
						DlgLinearArray.SetChildNode(treeNode, cl);
						tn.Nodes.Add(treeNode);
					}
				}
				else if (tn.Tag is DbSubject)
				{
					DbSubject dbSubject = (DbSubject)tn.Tag;
					if (dbCategory.ParentId == dbSubject.Guid)
					{
						TreeNode treeNode2 = new TreeNode(dbCategory.ToString());
						treeNode2.Name = dbCategory.Name;
						treeNode2.Tag = dbCategory;
						treeNode2.ImageIndex = 1;
						if (dbCategory.Limit)
						{
							treeNode2.ForeColor = System.Drawing.Color.Red;
						}
						DlgLinearArray.SetChildNode(treeNode2, cl);
						tn.Nodes.Add(treeNode2);
					}
				}
			}
		}

		private void rbtModel_CheckedChanged(object sender, EventArgs e)
		{
			if (this.rbtModel.Checked)
			{
				this.PlaceType = PlaceType.PickElement;
				this.temp = this.rbtModel;
				this.tvFamliy.Nodes.Clear();
				this.lbxType.Items.Clear();
				this.pictureBox1.Image = null;
			}
		}

		private void btnOK_Click(object sender, EventArgs e)
		{
			if (this.txtNum.Text == "" || this.txtAngle.Text == "")
			{
				YJKMessageBox.Show("请输入正确的数量或角度。");
				return;
			}
			if ((this.rbtLib.Checked || this.rbtProject.Checked) && this.tvFamliy.SelectedNode == null)
			{
				YJKMessageBox.Show("请输选择具体的族。");
				return;
			}
			if (this.rbtLib.Checked && this.tvFamliy.SelectedNode.Tag.GetType() != typeof(DbFamily))
			{
				YJKMessageBox.Show("请输选择具体的族。");
				return;
			}
			if (this.rbtProject.Checked && this.tvFamliy.SelectedNode.Tag.GetType() != typeof(Family))
			{
				YJKMessageBox.Show("请输选择具体的族。");
				return;
			}
			if (this.lbxType.SelectedItem != null && this.lbxType.SelectedItem is string)
			{
				DbFamily dbFamily = this.tvFamliy.SelectedNode.Tag as DbFamily;
				DbFamilySymbol dbFamilySymbol = dbFamily.Database.TypeTable[dbFamily, this.lbxType.SelectedItem.ToString()];
				this.FamilySymbol = dbFamilySymbol.Create(this.revit.Application.ActiveUIDocument.Document);
				this.HostCode = this.FamilySymbol.Family.get_Parameter(BuiltInParameter.FAMILY_HOSTING_BEHAVIOR).AsInteger();
			}
			else if (this.lbxType.SelectedItem != null && this.lbxType.SelectedItem is FamilySymbol)
			{
				this.FamilySymbol = (this.lbxType.SelectedItem as FamilySymbol);
				this.HostCode = this.FamilySymbol.Family.get_Parameter(BuiltInParameter.FAMILY_HOSTING_BEHAVIOR).AsInteger();
			}
			if (this.PlaceType != PlaceType.PickElement && this.FamilySymbol == null)
			{
				YJKMessageBox.Show("请选择阵列族。");
				return;
			}
			this.Num = Convert.ToInt32(this.txtNum.Text);
			this.Angle = Convert.ToDouble(this.txtAngle.Text) / 180.0 * Math.PI;
			this.Redo = this.cbxRedo.Checked;
			this.AutoRotation = this.cbxAutoRotation.Checked;
			base.DialogResult = DialogResult.OK;
			base.Close();
		}

		private void btnCancel_Click(object sender, EventArgs e)
		{
			base.Close();
		}

		private void tvFamliy_AfterSelect(object sender, TreeViewEventArgs e)
		{
			if (this.tvFamliy.SelectedNode != null && this.tvFamliy.SelectedNode.Tag is DbFamily)
			{
				this.lbxType.Items.Clear();
				DbFamily dbFamily = this.tvFamliy.SelectedNode.Tag as DbFamily;
				this.pictureBox1.Image = dbFamily.Image;
				using (List<string>.Enumerator enumerator = dbFamily.Database.TypeTable[dbFamily].GetEnumerator())
				{
					while (enumerator.MoveNext())
					{
						string item = enumerator.Current;
						this.lbxType.Items.Add(item);
					}
					goto IL_23E;
				}
			}
			if (this.tvFamliy.SelectedNode != null && this.tvFamliy.SelectedNode.Tag is Family)
			{
				try
				{
					this.lbxType.Items.Clear();
					Family family = this.tvFamliy.SelectedNode.Tag as Family;
					FamilyUtil.GetFamilyPreview(this.revit.Application, family.Name, this.pictureBox1);
					foreach (FamilySymbol item2 in family.GetSymbols())
					{
						this.lbxType.Items.Add(item2);
					}
					goto IL_23E;
				}
				catch (Exception)
				{
					this.rbtModel.Checked = true;
					goto IL_23E;
				}
			}
			if (this.tvFamliy.SelectedNode != null && this.tvFamliy.SelectedNode.Tag is DbCategory && this.tvFamliy.SelectedNode.Nodes.Count < 1)
			{
				foreach (DbFamily dbFamily2 in (this.tvFamliy.SelectedNode.Tag as DbCategory).GetAllFamilies(false, CheckType.All))
				{
					TreeNode treeNode = new TreeNode(dbFamily2.Name);
					treeNode.Tag = dbFamily2;
					this.tvFamliy.SelectedNode.Nodes.Add(treeNode);
					this.tvFamliy.ExpandAll();
				}
			}
			IL_23E:
			if (this.lbxType.Items.Count > 0)
			{
				this.lbxType.SelectedIndex = 0;
			}
		}

		private bool IsValidating(string numStr, int minRange, int maxRange)
		{
			try
			{
				int num = Convert.ToInt32(numStr);
				if (Geometry.LessThan((double)num, (double)minRange))
				{
					return false;
				}
				if (Geometry.GreaterThan((double)num, (double)maxRange))
				{
					return false;
				}
			}
			catch (Exception)
			{
				return false;
			}
			return true;
		}

		private void txtNum_TextChanged(object sender, EventArgs e)
		{
			if (!this.IsValidating(this.txtNum.Text, 1, 10000))
			{
				YJKMessageBox.Show("阵列数目必须为正整数");
				this.txtNum.Text = this.Num.ToString("f0");
				return;
			}
			this.Num = Convert.ToInt32(this.txtNum.Text);
		}

		private static DlgLinearArray dla;

		private ExternalCommandData revit;

		private RadioButton temp;

		public List<FamilyLibDatabase> dbs = new List<FamilyLibDatabase>();

		public int Num = 5;

		public double Angle;

		public bool Redo = true;

		public FamilySymbol FamilySymbol;

		public PlaceType PlaceType;

		public bool AutoRotation;

		public int HostCode;
	}
}
